﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using WEIShareSL.ServiceReference1;

namespace WEIShareSL
{
    public partial class MainPage : UserControl
    {
        public const string DefaultOrderByColumn = "uxOverall";
        public const string DefaultOrderByDirection = "DESC";
        public Uri DownloadAppUrl;

        #region Paging Properties

        private int _totalPages = 1;
        /// <summary>
        /// The total amount of pages that exist
        /// </summary>
        public int TotalPages { get { return _totalPages; } set { _totalPages = value; } }

        private int _pageNumber = 1;
        /// <summary>
        /// The Page Number that the Listing Page was on
        /// </summary>
        public int PageNumber { get { return _pageNumber; } set { _pageNumber = value; } }

        private int _pageSize = 50;
        /// <summary>
        /// The Page Size that the Listing Page was set to
        /// </summary>
        public int PageSize { get { return _pageSize; } set { _pageSize = value; } }

        private string _searchQuery = String.Empty;
        /// <summary>
        /// The Search Query that the Listing Page was set as
        /// </summary>
        public string SearchQuery { get { return _searchQuery; } set { _searchQuery = value; } }

        private string _orderBy = "SystemScore";
        /// <summary>
        /// The column that the Listing Page was ordered by
        /// </summary>
        public string OrderBy { get { return _orderBy; } set { _orderBy = value; } }

        private string _orderByDirection = "DESC";
        /// <summary>
        /// The direction that the ordered column that the Listing Page was set to
        /// </summary>
        public string OrderByDirection { get { return _orderByDirection; } set { _orderByDirection = value; } }

        private bool ShowingTopResults = true;


        private AdvancedSearch _advancedSearch = null;
        /// <summary>
        /// The Advanced Search Class that filters the results by set columns and ranges
        /// </summary>
        public AdvancedSearch AdvancedSearch { get { return _advancedSearch; } set { _advancedSearch = value; } }

        #endregion


        Storyboard myDelay = new Storyboard();


        WindowsExperienceServiceClient serviceClient;

        public MainPage()
        {
            InitializeComponent();

            if (App.Current.Resources.Contains("WCFServiceLocation")
               && !String.IsNullOrEmpty(App.Current.Resources["WCFServiceLocation"] as string))
            {
                EndpointAddress endpointAddress = new EndpointAddress(App.Current.Resources["WCFServiceLocation"].ToString());
                serviceClient = new WindowsExperienceServiceClient("CustomBinding_IWindowsExperienceService", endpointAddress);
            }
            else
            {
                serviceClient = new WindowsExperienceServiceClient();
            }

            myDelay.Duration = TimeSpan.FromMilliseconds(2000);
            myDelay.Completed += new EventHandler(myDelayCompleted);
            myDelay.Begin();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        }

        void myDelayCompleted(object sender, EventArgs e)
        {
            uxSBIntro.Begin();
        }


        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            uxSBHomeLoaderWheel.Begin();

            // Import Content
            WebClient webClient = new WebClient();
            webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
            webClient.DownloadStringAsync(new Uri("Content.xml", UriKind.Relative));

            // Wire Up and Populate Home Top 2 System Summary
  
            PageRequest pageRequest = new PageRequest();
            pageRequest.PageNumber = 1;
            pageRequest.PageSize = 2;
            pageRequest.OrderBy = "SystemScore";
            pageRequest.OrderByDirection = DefaultOrderByDirection;
            pageRequest.GroupResults = true;
            serviceClient.GetPagedWindowsAssessmentAsync(pageRequest);
            serviceClient.GetPagedWindowsAssessmentCompleted += new EventHandler<GetPagedWindowsAssessmentCompletedEventArgs>(serviceClient_GetPageHomeSystemSummary);

            // Set Default Paging
            SetPageRequest();
            serviceClient.GetPagedAdvancedSearchWindowsAssessmentCompleted += new EventHandler<GetPagedAdvancedSearchWindowsAssessmentCompletedEventArgs>(serviceClient_GetPagedAdvancedSearchWindowsAssessmentCompleted);

            // Wire Up Order By Events
            uxOverall.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxProcessor.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxMemory.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxGraphics.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxGamingGraphics.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxPrimaryHardDisk.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);
            uxTouchPoints.MouseLeftButtonUp += new MouseButtonEventHandler(uxOrderBy_MouseLeftButtonUp);

            // Wire Up Navigation
            uxFirstPageLink.Click += new RoutedEventHandler(uxFirstPageLink_Click);
            uxPreviousPageLink.Click += new RoutedEventHandler(uxPreviousPageLink_Click);
            uxNextPageLink.Click += new RoutedEventHandler(uxNextPageLink_Click);
            uxLastPageLink.Click += new RoutedEventHandler(uxLastPageLink_Click);

            // Wire Up Searches
            uxSimpleSearchKeywords.KeyUp += new KeyEventHandler(uxSimpleSearchKeywords_KeyUp);
            uxSimpleSearchSubmit.MouseLeftButtonUp += new MouseButtonEventHandler(uxSimpleSearchSubmit_MouseLeftButtonUp);
            uxSimpleSearchReset.MouseLeftButtonUp += new MouseButtonEventHandler(uxSimpleSearchReset_MouseLeftButtonUp);
            uxHandySearchKeywords.KeyUp += new KeyEventHandler(uxHandySearchKeywords_KeyUp);
            uxHandySearchSubmit.Click += new RoutedEventHandler(uxHandySearchSubmit_Click);
            uxAdvancedSearchReset.Click += new RoutedEventHandler(uxAdvancedSearchReset_Click);
            uxAdvancedSearchSubmit.Click += new RoutedEventHandler(uxAdvancedSearchSubmit_Click);

            // Wire Up Advanced Search
            uxAdvancedSearchLink.Click += new RoutedEventHandler(uxAdvancedSearchLink_Click);
            uxAdvancedSearchLink2.Click += new RoutedEventHandler(uxAdvancedSearchLink_Click);
            uxAdvancedSearchClose.Click += new RoutedEventHandler(uxAdvancedSearchClose_Click);

            // Wire Up Download Panel
            uxDownloadLink.Click += new RoutedEventHandler(uxDownloadLink_Click);
            uxDownloadClose.Click += new RoutedEventHandler(uxDownloadClose_Click);

            // Wire Up click events to go to Home Screen
            uxHomeLink.Click += new RoutedEventHandler(uxHomeLink_Click);
            uxLogo.MouseLeftButtonUp += new MouseButtonEventHandler(uxLogo_MouseLeftButtonUp);

            // Wire Up Results Buttons
            uxBrowseLink.Click += new RoutedEventHandler(uxBrowseLink_Click);
            uxShowAllTopRatedSystems.Click += new RoutedEventHandler(uxShowAllTopRatedSystems_Click);

            //Wire Up Download Buttons
            uxInstallNow.Click += new RoutedEventHandler(uxInstallNow_Click);
            uxDownloadNow.Click += new RoutedEventHandler(uxDownloadNow_Click);

            //scroll view mouse wheel capture
            uxScrollView.MouseWheel += new MouseWheelEventHandler(uxScrollView_MouseWheel);

            // Load Advanced Search Drop Downs
            PopulateAdvancedSearchDropDowns();

        }

        

        /// <summary>
        /// Handles the mousewheel event while the silverlight is focused and the mouse is over reults listing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void uxScrollView_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            int sign = -Math.Sign(e.Delta);
            uxScrollView.ScrollToVerticalOffset(uxScrollView.VerticalOffset + sign * 50);
        }


        #region Paging Click Handlers
        void uxLastPageLink_Click(object sender, RoutedEventArgs e)
        {
            PageNumber = TotalPages;

            SetPageRequest();
        }

        void uxNextPageLink_Click(object sender, RoutedEventArgs e)
        {
            PageNumber++;

            SetPageRequest();
        }

        void uxPreviousPageLink_Click(object sender, RoutedEventArgs e)
        {
            PageNumber--;

            SetPageRequest();
        }

        void uxFirstPageLink_Click(object sender, RoutedEventArgs e)
        {
            PageNumber = 1;

            SetPageRequest();
        }
        #endregion


        /// <summary>
        /// Checks the selections setup in the advanced search.
        /// </summary>
        /// <param name="current">The advanced search containing the search selections</param>
        /// <returns>True if successful/valid, otherwise false</returns>
        bool CheckAdvancedSearchSelectionsIsValid(AdvancedSearch current)
        {
            //check values
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            if (AdvancedSearch.SystemScoreMin > AdvancedSearch.SystemScoreMax)
                sb.AppendLine(" - Overall Rating");

            if (AdvancedSearch.ProcessorNumCoresMin > AdvancedSearch.ProcessorNumCoresMax)
                sb.AppendLine(" - Processor: # of Cores");

            if (AdvancedSearch.ProcessorL2CacheSizeMin > AdvancedSearch.ProcessorL2CacheSizeMax)
                sb.AppendLine(" - Processor: L2Cache");

            if (AdvancedSearch.MemoryPhysicalSizeMin > AdvancedSearch.MemoryPhysicalSizeMax)
                sb.AppendLine(" - Memory: Capacity");

            if (AdvancedSearch.MemorySpeedMin > AdvancedSearch.MemorySpeedMax)
                sb.AppendLine(" - Memory: Speed");

            if (AdvancedSearch.GraphicsMemoryMin > AdvancedSearch.GraphicsMemoryMax)
                sb.AppendLine(" - Graphics:  Memory");

            if (AdvancedSearch.MonitorsCountMin > AdvancedSearch.MonitorsCountMax)
                sb.AppendLine(" - Graphics: # of Monitors");

            if (AdvancedSearch.DiskSizeMin > AdvancedSearch.DiskSizeMax)
                sb.AppendLine(" - Hard Drive");


            if (sb.Length > 0)
            {
                MessageBox.Show
                (
                    "Try your search with a minimum number smaller than your maximum number for the following:" +
                    Environment.NewLine + Environment.NewLine + sb.ToString(), 
                    "Advanced Search Validation Check", 
                    MessageBoxButton.OK
                );
            }

            return (sb.Length < 1);
        }


        /// <summary>
        /// Runs the Advanced Search
        /// </summary>
        void uxAdvancedSearchSubmit_Click(object sender, RoutedEventArgs e)
        {
            RunAdvancedSearch();
        }

        /// <summary>
        /// Resets Advanced Search Parameters
        /// </summary>
        void uxAdvancedSearchReset_Click(object sender, RoutedEventArgs e)
        {
            ResetAdvancedSearch();
        }

        /// <summary>
        /// Opens download App Url
        /// </summary>
        void OpenDownloadAppUrl()
        {
            HtmlPage.PopupWindow(DownloadAppUrl, "_blank", new HtmlPopupWindowOptions());
        }

        /// <summary>
        /// Displays the Top Rated Systems Results
        /// </summary>
        void uxSeeResults_Click(object sender, RoutedEventArgs e)
        {
            ShowTopResults();
        }

        void ShowTopResults()
        {
            // Determines if the application is currently show the top results.  If not, then reset the results and set the page request for the Web Service call
            if (!ShowingTopResults)
            {
                ResetResults();

                SetPageRequest();
            }

            // Begin Story Board to Display Results
            uxSBOpenResultsPage.Begin();
        }

        //Intel(R) Core(TM)2 Quad CPU           @ 2.40GHz

        /// <summary>
        /// Populates Content from XML File
        /// </summary>
        void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            XDocument xDocument = XDocument.Parse(e.Result);

            uxHomeTitle.Text = xDocument.Element("Content").Element("Home").Element("Title").Value;
            uxHomeContent.Text = xDocument.Element("Content").Element("Home").Element("Content").Value;
            uxDownloadContent.Text = xDocument.Element("Content").Element("Download").Element("Content").Value;
            DownloadAppUrl = new Uri(xDocument.Element("Content").Element("Shared").Element("DownloadAppUrl").Value);
        }

        /// <summary>
        /// Populates the Advanced Search Drop Downs
        /// </summary>
        private void PopulateAdvancedSearchDropDowns()
        {
            // Populate List Items for System Scores
            List<ComboBoxListItem> SystemScoreListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 7; i++)
            {
                SystemScoreListItems.Add(new ComboBoxListItem() { Text = i + ".0", Value = i + ".0" });
            }
            SystemScoreListItems.Add(new ComboBoxListItem() { Text = "7.9", Value = "7.9" });
            uxSystemScoreMin.ItemsSource = SystemScoreListItems;
            uxSystemScoreMin.DisplayMemberPath = "Text";
            uxSystemScoreMin.SelectedIndex = 0;

            uxSystemScoreMax.ItemsSource = SystemScoreListItems;
            uxSystemScoreMax.DisplayMemberPath = "Text";
            uxSystemScoreMax.SelectedIndex = SystemScoreListItems.Count - 1;


            // Populate List items for Number of Processor Cores
            List<ComboBoxListItem> ProcessorNumCoresListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 8; i++)
            {
                ProcessorNumCoresListItems.Add(new ComboBoxListItem() { Text = i.ToString(), Value = i.ToString() });
            }
            uxProcessorNumCoresMin.ItemsSource = ProcessorNumCoresListItems;
            uxProcessorNumCoresMin.DisplayMemberPath = "Text";
            uxProcessorNumCoresMin.SelectedIndex = 0;

            uxProcessorNumCoresMax.ItemsSource = ProcessorNumCoresListItems;
            uxProcessorNumCoresMax.DisplayMemberPath = "Text";
            uxProcessorNumCoresMax.SelectedIndex = ProcessorNumCoresListItems.Count - 1;

            // Populate List Items for L2Cache Size
            List<ComboBoxListItem> L2CacheListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 24; i++)
            {
                L2CacheListItems.Add(new ComboBoxListItem() { Text = i + " MB", Value = (i * Math.Pow(1024, 2)).ToString() });
            }
            uxProcessorL2CacheSizeMin.ItemsSource = L2CacheListItems;
            uxProcessorL2CacheSizeMin.DisplayMemberPath = "Text";
            uxProcessorL2CacheSizeMin.SelectedIndex = 0;

            uxProcessorL2CacheSizeMax.ItemsSource = L2CacheListItems;
            uxProcessorL2CacheSizeMax.DisplayMemberPath = "Text";
            uxProcessorL2CacheSizeMax.SelectedIndex = L2CacheListItems.Count - 1;

            // Populate Memory Type
            List<ComboBoxListItem> MemoryTypeListItems = new List<ComboBoxListItem>();
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "", Text = " " });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "2", Text = "DRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "3", Text = "Synchronous DRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "4", Text = "Cache DRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "5", Text = "EDO" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "6", Text = "EDRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "7", Text = "VRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "8", Text = "SRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "9", Text = "RAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "10", Text = "ROM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "11", Text = "Glash" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "12", Text = "EEPROM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "13", Text = "FEPROM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "14", Text = "EPROM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "15", Text = "CDRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "16", Text = "3DRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "17", Text = "SDRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "18", Text = "SGRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "19", Text = "RDRAM" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "20", Text = "DDR" });
            MemoryTypeListItems.Add(new ComboBoxListItem() { Value = "21", Text = "DDR-2" });
            uxMemoryType.ItemsSource = MemoryTypeListItems;
            uxMemoryType.DisplayMemberPath = "Text";
            uxMemoryType.SelectedIndex = 0;

            // Populate List Items for Memory Size
            List<ComboBoxListItem> MemoryPhysicalSizeListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 96; i += 4)
            {
                MemoryPhysicalSizeListItems.Add(new ComboBoxListItem() { Text = i + " GB", Value = (i * Math.Pow(1024, 3)).ToString() });
            }
            uxMemoryPhysicalSizeMin.ItemsSource = MemoryPhysicalSizeListItems;
            uxMemoryPhysicalSizeMin.DisplayMemberPath = "Text";
            uxMemoryPhysicalSizeMin.SelectedIndex = 0;

            uxMemoryPhysicalSizeMax.ItemsSource = MemoryPhysicalSizeListItems;
            uxMemoryPhysicalSizeMax.DisplayMemberPath = "Text";
            uxMemoryPhysicalSizeMax.SelectedIndex = MemoryPhysicalSizeListItems.Count - 1;

            // Populate List Items for Memory Speed
            List<ComboBoxListItem> MemorySpeedListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 6000; i += 500)
            {
                MemorySpeedListItems.Add(new ComboBoxListItem() { Text = i + " MHz", Value = i.ToString() });
            }
            uxMemorySpeedMin.ItemsSource = MemorySpeedListItems;
            uxMemorySpeedMin.DisplayMemberPath = "Text";
            uxMemorySpeedMin.SelectedIndex = 0;

            uxMemorySpeedMax.ItemsSource = MemorySpeedListItems;
            uxMemorySpeedMax.DisplayMemberPath = "Text";
            uxMemorySpeedMax.SelectedIndex = MemorySpeedListItems.Count - 1;

            // Populate List Items for Graphics Memory Size
            List<ComboBoxListItem> GraphicsMemoryListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 2205; i += 256)
            {
                GraphicsMemoryListItems.Add(new ComboBoxListItem() { Text = i + " MB", Value = (i * Math.Pow(1024, 2)).ToString() });
            }
            uxGraphicsMemoryMin.ItemsSource = GraphicsMemoryListItems;
            uxGraphicsMemoryMin.DisplayMemberPath = "Text";
            uxGraphicsMemoryMin.SelectedIndex = 0;

            uxGraphicsMemoryMax.ItemsSource = GraphicsMemoryListItems;
            uxGraphicsMemoryMax.DisplayMemberPath = "Text";
            uxGraphicsMemoryMax.SelectedIndex = GraphicsMemoryListItems.Count - 1;

            // Populate List Items for Monitors Count
            List<ComboBoxListItem> MonitorsCountListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 16; i++)
            {
                MonitorsCountListItems.Add(new ComboBoxListItem() { Text = i.ToString(), Value = i.ToString() });
            }
            uxMonitorsCountMin.ItemsSource = MonitorsCountListItems;
            uxMonitorsCountMin.DisplayMemberPath = "Text";
            uxMonitorsCountMin.SelectedIndex = 0;

            uxMonitorsCountMax.ItemsSource = MonitorsCountListItems;
            uxMonitorsCountMax.DisplayMemberPath = "Text";
            uxMonitorsCountMax.SelectedIndex = MonitorsCountListItems.Count - 1;

            // Populate List Items for Disk Size
            List<ComboBoxListItem> DiskSizeListItems = new List<ComboBoxListItem>();
            for (int i = 0; i <= 3200; i += 200)
            {
                DiskSizeListItems.Add(new ComboBoxListItem() { Text = i + " GB", Value = (i * Math.Pow(1024, 3)).ToString() });
            }
            uxDiskSizeMin.ItemsSource = DiskSizeListItems;
            uxDiskSizeMin.DisplayMemberPath = "Text";
            uxDiskSizeMin.SelectedIndex = 0;

            uxDiskSizeMax.ItemsSource = DiskSizeListItems;
            uxDiskSizeMax.DisplayMemberPath = "Text";
            uxDiskSizeMax.SelectedIndex = DiskSizeListItems.Count - 1;

        }

        /// <summary>
        /// Gets response from Web Service to populate "Today's Top Systems"
        /// </summary>
        void serviceClient_GetPageHomeSystemSummary(object sender, GetPagedWindowsAssessmentCompletedEventArgs e)
        {
            // Removes Loading... Screen
            uxHomeLoader.Visibility = Visibility.Collapsed;
            uxHomeLoader.Opacity = 0;
            uxSBHomeLoaderWheel.Stop();

            // Retrieves Data from Web Service
            var pageResponse = e.Result.Data;

            // Gets PagedListing that should return the top two systems
            List<WindowsAssessment> pagedListing = pageResponse.PageListing.ToList();

            // Loops through the Paged Listings and populates the System Summary for "Today's Top Systems"
            // This loop continues until it cannot find any more System Summary Xaml for "Today's Top Systems"
            int count = 0;
            foreach (WindowsAssessment windowsAssessment in pagedListing)
            {
                count++;
                SystemSummary uxSystemSummary = FindName("uxSystemSummary" + count) as SystemSummary;
                if (uxSystemSummary != null)
                {
                    uxSystemSummary.OverAllText.Text = windowsAssessment.OverallColumnText;
                    uxSystemSummary.ProcessorText.Text = windowsAssessment.ProcessorColumnText;
                    uxSystemSummary.MemoryText.Text = windowsAssessment.MemoryColumnText;
                    uxSystemSummary.GraphicsText.Text = windowsAssessment.GraphicsColumnText;
                    uxSystemSummary.GamingGraphicsText.Text = windowsAssessment.GamingGraphicsColumnText + " Total available graphics memory";
                    uxSystemSummary.PrimaryHardDiskText.Text = windowsAssessment.PrimaryHardDiskColumnText;
                    uxSystemSummary.SystemScoreText.Text = windowsAssessment.SystemScore.GetValueOrDefault(0).ToString();
                    uxSystemSummary.uxSeeResults.Click += new RoutedEventHandler(uxSeeResults_Click);
                }
                else
                {
                    break;
                }
            }

        }

        /// <summary>
        /// Gets response from Web Service to populate results listing
        /// </summary>
        void serviceClient_GetPagedAdvancedSearchWindowsAssessmentCompleted(object sender, GetPagedAdvancedSearchWindowsAssessmentCompletedEventArgs e)
        {
            uxResultsLoader.Visibility = Visibility.Collapsed;
            uxResultsLoader.Opacity = 0;
            uxSBResultsLoaderWheel.Stop();
            var PagedResults = e.Result;

            List<WindowsAssessment> pagedListing = PagedResults.Data.PageListing.ToList();
            uxData.ItemsSource = pagedListing;

            TotalPages = PagedResults.Data.TotalPages;
            PageNumber = PagedResults.Data.PageNumber;

            string resultsFirstIndex = (((PageNumber - 1) * PageSize) + 1).ToString();
            string resultsLastIndex = Math.Min((PageSize * PageNumber), (Convert.ToInt32(resultsFirstIndex) + pagedListing.Count - 1)).ToString();

            uxFirstPageLink.IsEnabled = true;
            uxFirstPageLink.Opacity = 1;
            uxPreviousPageLink.IsEnabled = true;
            uxPreviousPageLink.Opacity = 1;
            uxNextPageLink.IsEnabled = true;
            uxNextPageLink.Opacity = 1;
            uxLastPageLink.IsEnabled = true;
            uxLastPageLink.Opacity = 1;

            if (PageNumber == 1)
            {
                uxFirstPageLink.IsEnabled = false;
                uxFirstPageLink.Opacity = 0.35;
                uxPreviousPageLink.IsEnabled = false;
                uxPreviousPageLink.Opacity = 0.35;
            }

            if (PageNumber == TotalPages)
            {
                uxNextPageLink.IsEnabled = false;
                uxNextPageLink.Opacity = 0.35;
                uxLastPageLink.IsEnabled = false;
                uxLastPageLink.Opacity = 0.35;
            }

            if(resultsLastIndex != "0")
                uxResultsSummary.Text = String.Format("Results {0}-{1}", resultsFirstIndex, resultsLastIndex);
            else
                uxResultsSummary.Text = String.Format("Results 0");

            uxScrollView.ScrollToVerticalOffset(0);

        }


        void uxOrderBy_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Grid gridColumn = sender as Grid;

            // Sets the Order By based on the Column Clicked
            SetOrderBy(gridColumn);

            // Sets the Page Request to the Web Service
            SetPageRequest();
        }

        /// <summary>
        /// Sets up all of the UI changes to handle the correct selected column as well as properly populating OrderBy and OrderByDirection
        /// </summary>
        /// <param name="gridColumn">The column to select and order by</param>
        private void SetOrderBy(Grid gridcolumn)
        {
            SetOrderBy(gridcolumn, false);
        }

        /// <summary>
        /// Sets up all of the UI changes to handle the correct selected column as well as properly populating OrderBy and OrderByDirection
        /// </summary>
        /// <param name="gridColumn">The column to select and order by</param>
        /// <param name="useDefaultOrderByDirection">Designates whether or not to order by the default direction setting or toggle current order by direction</param>
        private void SetOrderBy(Grid gridColumn, bool useDefaultOrderByDirection)
        {

            // Collapse all Order By Arrows
            uxOverallOrderBy.Visibility = Visibility.Collapsed;
            uxProcessorOrderBy.Visibility = Visibility.Collapsed;
            uxMemoryOrderBy.Visibility = Visibility.Collapsed;
            uxGraphicsOrderBy.Visibility = Visibility.Collapsed;
            uxTouchPointsOrderBy.Visibility = Visibility.Collapsed;
            uxGamingGraphicsOrderBy.Visibility = Visibility.Collapsed;
            uxPrimaryHardDiskOrderBy.Visibility = Visibility.Collapsed;

            // Resets all ForeGround Colors for the Order By Titles
            uxOverallText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxProcessorText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxMemoryText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxGraphicsText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxTouchPointsText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxGamingGraphicsText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);
            uxPrimaryHardDiskText.Foreground = new SolidColorBrush((Color)App.Current.Resources["LightBlueBackground"]);

            // Select the correct Column
            uxSelectedColumn.SetValue(Grid.ColumnProperty, gridColumn.GetValue(Grid.ColumnProperty));

            // Sets the Foreground for the Selected Column
            TextBlock columnText = FindName(gridColumn.Name + "Text") as TextBlock;
            columnText.Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));

            // Sets the orderBy and Arrows based on the grid column that was passed in
            string orderBy = "";
            switch (gridColumn.Name)
            {
                case "uxOverall":
                    orderBy = "SystemScore";
                    uxOverallOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxProcessor":
                    orderBy = "CpuScore";
                    uxProcessorOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxMemory":
                    orderBy = "MemoryScore";
                    uxMemoryOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxGraphics":
                    orderBy = "GraphicsScore";
                    uxGraphicsOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxTouchPoints":
                    orderBy = "TouchPointCount";
                    uxTouchPointsOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxGamingGraphics":
                    orderBy = "GamingScore";
                    uxGamingGraphicsOrderBy.Visibility = Visibility.Visible;
                    break;
                case "uxPrimaryHardDisk":
                    orderBy = "DiskScore";
                    uxPrimaryHardDiskOrderBy.Visibility = Visibility.Visible;
                    break;
                default:
                    orderBy = "SystemScore";
                    uxOverallOrderBy.Visibility = Visibility.Visible;
                    break;
            }

            // Sets the OrderByDirection and OrderBy
            if (useDefaultOrderByDirection)
                OrderByDirection = DefaultOrderByDirection;
            else
                OrderByDirection = orderBy != OrderBy ? DefaultOrderByDirection : OrderByDirection.Equals("DESC", StringComparison.OrdinalIgnoreCase) ? "ASC" : "DESC";

            OrderBy = orderBy;

            // Properly Sets the opacity of the Order by Arrows to delineate direction for the column
            Path orderByASC = FindName(gridColumn.Name + "OrderByASC") as Path;
            Path orderByDESC = FindName(gridColumn.Name + "OrderByDESC") as Path;
            orderByASC.Opacity = OrderByDirection.Equals("ASC", StringComparison.OrdinalIgnoreCase) ? 1 : 0.5;
            orderByDESC.Opacity = OrderByDirection.Equals("DESC", StringComparison.OrdinalIgnoreCase) ? 1 : 0.5;
        }

        /// <summary>
        /// Displays Loading... Sets the Page Request and Calls the Web Service
        /// </summary>
        private void SetPageRequest()
        {
            //remove the results count
            uxResultsSummary.Text = "";

            uxSBResultsLoaderWheel.Begin();
            uxResultsLoader.Visibility = Visibility.Visible;
            uxResultsLoader.Opacity = 1;

            AdvancedSearch advancedSearch = AdvancedSearch;

            PageRequest pageRequest = new PageRequest();
            pageRequest.SearchQuery = SearchQuery;
            pageRequest.PageNumber = PageNumber;
            pageRequest.PageSize = PageSize;
            pageRequest.OrderBy = OrderBy;
            pageRequest.OrderByDirection = OrderByDirection;
            pageRequest.GroupResults = true;
            serviceClient.GetPagedAdvancedSearchWindowsAssessmentAsync(pageRequest, advancedSearch);

            if (advancedSearch == null && String.IsNullOrEmpty(pageRequest.SearchQuery) && pageRequest.PageNumber == 1 && pageRequest.OrderBy == "SystemScore" && pageRequest.OrderByDirection == "DESC")
                ShowingTopResults = true;
            else
                ShowingTopResults = false;


        }

        void uxSimpleSearchKeywords_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                // Set the Search Query
                RunSimpleSearch(uxSimpleSearchKeywords.Text);
            }
        }

        void uxSimpleSearchSubmit_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            AdjustStandardSearchButtons(false);
            // Set the Search Query
            RunSimpleSearch(uxSimpleSearchKeywords.Text);
        }


        void uxSimpleSearchReset_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            AdjustStandardSearchButtons(true);
            //Use basic search which resets the search settings
            ShowTopResults();
        }


        /// <summary>
        /// Used to setup the search submit/reset button placement and display
        /// </summary>
        /// <param name="resetToNoSearch"></param>
        void AdjustStandardSearchButtons(bool resetToNoSearch)
        {
            if (resetToNoSearch)
            {
                uxSimpleSearchReset.Visibility = System.Windows.Visibility.Collapsed;
                uxSimpleSearchSubmit.Margin = new Thickness(-30, 3, 0, 0);
            }
            else
            {
                uxSimpleSearchSubmit.Margin = new Thickness(-65, 3, 0, 0);
                uxSimpleSearchReset.Visibility = System.Windows.Visibility.Visible;
            }
        }

        void uxHandySearchKeywords_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                // Searches the Data for resuls based on query
                RunSimpleSearch(uxHandySearchKeywords.Text);
            }
        }

        void uxHandySearchSubmit_Click(object sender, RoutedEventArgs e)
        {
            // Searches the Data for resuls based on query
            RunSimpleSearch(uxHandySearchKeywords.Text);
        }


        /// <summary>
        /// Searchs the data for results based on search query and then populates both search text boxes.  A Simple Search such as this will search
        /// on top of any Advanced Search that was performed.
        /// </summary>
        /// <param name="searchQuery">Search Query</param>
        void RunSimpleSearch(string searchQuery)
        {
            // Story Board to Open Results
            uxSBOpenResultsPage.Begin();

            // Sets the Search Query and populates simple search text boxes
            SearchQuery = searchQuery;
            uxHandySearchKeywords.Text = searchQuery;
            uxSimpleSearchKeywords.Text = searchQuery;

            // Sets the Page Request
            SetPageRequest();
        }

        void RunAdvancedSearch()
        {
            if (AdvancedSearch == null)
                AdvancedSearch = new AdvancedSearch();

            AdvancedSearch.ProcessorName = uxProcessorName.Text;
            if (!String.IsNullOrEmpty(((ComboBoxListItem)uxMemoryType.SelectedItem).Value))
                AdvancedSearch.MemoryTypeID = Convert.ToInt32(((ComboBoxListItem)uxMemoryType.SelectedItem).Value);
            AdvancedSearch.GraphicsAdapterDescription = uxGraphicsAdapterDescription.Text;

            AdvancedSearch.SystemScoreMin = Convert.ToDecimal(((ComboBoxListItem)uxSystemScoreMin.SelectedItem).Value);
            AdvancedSearch.SystemScoreMax = Convert.ToDecimal(((ComboBoxListItem)uxSystemScoreMax.SelectedItem).Value);
            AdvancedSearch.ProcessorNumCoresMin = Convert.ToInt32(((ComboBoxListItem)uxProcessorNumCoresMin.SelectedItem).Value);
            AdvancedSearch.ProcessorNumCoresMax = Convert.ToInt32(((ComboBoxListItem)uxProcessorNumCoresMax.SelectedItem).Value);
            AdvancedSearch.ProcessorL2CacheSizeMin = Convert.ToInt32(((ComboBoxListItem)uxProcessorL2CacheSizeMin.SelectedItem).Value);
            AdvancedSearch.ProcessorL2CacheSizeMax = Convert.ToInt32(((ComboBoxListItem)uxProcessorL2CacheSizeMax.SelectedItem).Value);
            AdvancedSearch.MemoryPhysicalSizeMin = Convert.ToInt64(((ComboBoxListItem)uxMemoryPhysicalSizeMin.SelectedItem).Value);
            AdvancedSearch.MemoryPhysicalSizeMax = Convert.ToInt64(((ComboBoxListItem)uxMemoryPhysicalSizeMax.SelectedItem).Value);
            AdvancedSearch.MemorySpeedMin = Convert.ToInt32(((ComboBoxListItem)uxMemorySpeedMin.SelectedItem).Value);
            AdvancedSearch.MemorySpeedMax = Convert.ToInt32(((ComboBoxListItem)uxMemorySpeedMax.SelectedItem).Value);
            AdvancedSearch.GraphicsMemoryMin = Convert.ToInt64(((ComboBoxListItem)uxGraphicsMemoryMin.SelectedItem).Value);
            AdvancedSearch.GraphicsMemoryMax = Convert.ToInt64(((ComboBoxListItem)uxGraphicsMemoryMax.SelectedItem).Value);
            AdvancedSearch.MonitorsCountMin = Convert.ToInt32(((ComboBoxListItem)uxMonitorsCountMin.SelectedItem).Value);
            AdvancedSearch.MonitorsCountMax = Convert.ToInt32(((ComboBoxListItem)uxMonitorsCountMax.SelectedItem).Value);
            AdvancedSearch.DiskSizeMin = Convert.ToInt64(((ComboBoxListItem)uxDiskSizeMin.SelectedItem).Value);
            AdvancedSearch.DiskSizeMax = Convert.ToInt64(((ComboBoxListItem)uxDiskSizeMax.SelectedItem).Value);


            //Check the values
            if (CheckAdvancedSearchSelectionsIsValid(AdvancedSearch))
            {
                uxSBCloseAdvancedSearchPanel.Begin();
                uxSBOpenResultsPage.Begin();

                // Reset the Paging
                ResetPaging();

                SetPageRequest();
            }
        }

        /// <summary>
        /// Resets the Score Results to display Top Systems
        /// </summary>
        void ResetResults()
        {
            // Resets Paging Info
            ResetPaging();

            // Resets Advanced Search including UI
            ResetAdvancedSearch();

            // Resets Simple Searches
            ResetSimpleSearch();
        }

        /// <summary>
        /// Resets the paging to page 1 and default Order By
        /// </summary>
        private void ResetPaging()
        {
            PageNumber = 1;
            SetOrderBy((Grid)FindName(DefaultOrderByColumn), true);
        }


        /// <summary>
        /// Resets the Advanced Search UI
        /// </summary>
        private void ResetAdvancedSearch()
        {
            AdvancedSearch = null;

            uxSystemScoreMin.SelectedIndex = 0;
            uxSystemScoreMax.SelectedIndex = uxSystemScoreMax.Items.Count - 1;
            uxProcessorName.Text = String.Empty;
            uxProcessorNumCoresMin.SelectedIndex = 0;
            uxProcessorNumCoresMax.SelectedIndex = uxProcessorNumCoresMax.Items.Count - 1;
            uxProcessorL2CacheSizeMin.SelectedIndex = 0;
            uxProcessorL2CacheSizeMax.SelectedIndex = uxProcessorL2CacheSizeMax.Items.Count - 1;
            uxMemoryType.SelectedIndex = 0;
            uxMemoryPhysicalSizeMin.SelectedIndex = 0;
            uxMemoryPhysicalSizeMax.SelectedIndex = uxMemoryPhysicalSizeMax.Items.Count - 1;
            uxMemorySpeedMin.SelectedIndex = 0;
            uxMemorySpeedMax.SelectedIndex = uxMemorySpeedMax.Items.Count - 1;
            uxGraphicsAdapterDescription.Text = String.Empty;
            uxGraphicsMemoryMin.SelectedIndex = 0;
            uxGraphicsMemoryMax.SelectedIndex = uxGraphicsMemoryMax.Items.Count - 1;
            uxDiskSizeMin.SelectedIndex = 0;
            uxDiskSizeMax.SelectedIndex = uxDiskSizeMax.Items.Count - 1;
            uxMonitorsCountMin.SelectedIndex = 0;
            uxMonitorsCountMax.SelectedIndex = uxMonitorsCountMax.Items.Count - 1;
        }

        /// <summary>
        /// Resets the Simple Search UI
        /// </summary>
        void ResetSimpleSearch()
        {
            SearchQuery = String.Empty;
            uxHandySearchKeywords.Text = String.Empty;
            uxSimpleSearchKeywords.Text = String.Empty;
        }

        /// <summary>
        /// Open and Close various panels & pages
        /// </summary>
        void uxHomeLink_Click(object sender, EventArgs e)
        {
            uxSBOpenHomePage.Begin();
        }

        void uxLogo_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            uxSBOpenHomePage.Begin();
        }

        void uxAdvancedSearchLink_Click(object sender, EventArgs e)
        {
            uxSBOpenAdvancedSearchPanel.Begin();
        }

        void uxAdvancedSearchClose_Click(object sender, EventArgs e)
        {
            uxSBCloseAdvancedSearchPanel.Begin();
        }

        void uxDownloadLink_Click(object sender, EventArgs e)
        {
            uxSBOpenDownloadPanel.Begin();
        }

        void uxDownloadClose_Click(object sender, EventArgs e)
        {
            uxSBCloseDownloadPanel.Begin();
        }

        void uxBrowseLink_Click(object sender, EventArgs e)
        {
            ShowTopResults();
        }

        void uxShowAllTopRatedSystems_Click(object sender, EventArgs e)
        {
            ShowTopResults();
        }

        void uxInstallNow_Click(object sender, EventArgs e)
        {
            OpenDownloadAppUrl();
        }

        void uxDownloadNow_Click(object sender, EventArgs e)
        {
            OpenDownloadAppUrl();
        }


    }

    public class ComboBoxListItem
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }
}
